package com.dkm.biz.gl.domain;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.dkm.base.api.annotion.SKGCacheEvict;
import com.dkm.base.api.constants.RedisConstants;
import com.dkm.base.api.service.IdGenerator;
import com.dkm.base.core.helper.SpringHelper;
import com.dkm.biz.domain.AbstractDomain;
import com.dkm.biz.gl.persistence.dao.EavAttrOptionDao;
import com.dkm.biz.gl.persistence.dao.EavAttrOptionQueryDao;
import com.dkm.biz.gl.persistence.dao.EavAttributeDao;
import com.dkm.biz.gl.persistence.dao.EavAttributeQueryDao;
import com.dkm.biz.gl.persistence.dao.EavValueDatetimeDao;
import com.dkm.biz.gl.persistence.dao.EavValueDecimalDao;
import com.dkm.biz.gl.persistence.dao.EavValueIntDao;
import com.dkm.biz.gl.persistence.dao.EavValueOptionsDao;
import com.dkm.biz.gl.persistence.dao.EavValueTextDao;
import com.dkm.biz.gl.persistence.dao.EavValueVarcharDao;
import com.dkm.biz.gl.persistence.entity.EavAttrOptionPo;
import com.dkm.biz.gl.persistence.entity.EavAttributePo;
import com.dkm.biz.gl.persistence.entity.EavSetPo;
import com.dkm.biz.gl.persistence.entity.EavValueDatetimePo;
import com.dkm.biz.gl.persistence.entity.EavValueDecimalPo;
import com.dkm.biz.gl.persistence.entity.EavValueIntPo;
import com.dkm.biz.gl.persistence.entity.EavValueOptionsPo;
import com.dkm.biz.gl.persistence.entity.EavValueVarcharPo;
import com.dkm.biz.gl.repository.EavAttrOptionRepository;
import com.dkm.biz.gl.repository.EavSetRepository;
import com.dkm.biz.gl.repository.EavValueDatetimeRepository;
import com.dkm.biz.gl.repository.EavValueDecimalRepository;
import com.dkm.biz.gl.repository.EavValueIntRepository;
import com.dkm.biz.gl.repository.EavValueOptionsRepository;
import com.dkm.biz.gl.repository.EavValueTextRepository;
import com.dkm.biz.gl.repository.EavValueVarcharRepository;
/**
 * 对象功能:属性 领域对象实体
 * 开发公司:SKG.COM
 * 开发人员:Yuki
 * 创建时间:2014-12-11 10:47:53
 */
@Service
@Scope("prototype")
public class EavAttribute extends AbstractDomain<String, EavAttributePo>{
	 
	 private EavAttributeDao eavAttributeDao = null;
	 private EavAttrOptionDao eavAttrOptionDao = null;
	  @Resource
	 IdGenerator idGenerator;
		@Resource
		EavAttributeQueryDao eavAttributeQueryDao;
		@Resource
		EavAttrOptionQueryDao eavAttrOptionQueryDao;
	 	@Resource
		 EavValueVarcharRepository eavValueVarcharRepository;
		@Resource
		EavValueIntRepository eavValueIntRepository;
		@Resource
		EavValueDecimalRepository eavValueDecimalRepository;
		@Resource
		EavValueDatetimeRepository eavValueDatetimeRepository;
		@Resource
		EavValueTextRepository eavValueTextRepository;
		@Resource
		EavValueOptionsRepository eavValueOptionsRepository;
		@Resource
		EavAttrOptionRepository eavAttrOptionRepository;
		@Resource
		EavValueVarcharDao eavValueVarcharDao;
		@Resource
		EavValueIntDao eavValueIntDao;
		@Resource
		EavValueDecimalDao eavValueDecimalDao;
		@Resource
		EavValueDatetimeDao eavValueDatetimeDao;
		@Resource
		EavValueTextDao eavValueTextDao;
		@Resource
		EavValueOptionsDao eavValueOptionsDao;
		@Resource 
		EavSetRepository eavSetRepository;

	protected void init(){
		eavAttributeDao = SpringHelper.getBean(EavAttributeDao.class);
		setDao(eavAttributeDao);
		eavAttrOptionDao = SpringHelper.getBean(EavAttrOptionDao.class);
		idGenerator  = SpringHelper.getBean(IdGenerator.class);
	}	 
	 
	@Override
	public void save(){
		
		EavAttributePo eavAttributePo = getData();
		/*if(!(eavAttributePo.getDataType().equals("options")&&eavAttributePo.getOpSelType().equals("tree"))){
			eavAttrOptionDao.deleteOptionbyAttrId(eavAttributePo.getId());
		}*/
		super.save();
		saveEavAttrOptions(eavAttributePo.getId(),eavAttributePo.getEavAttrOptionPoList());
	}
	
	public void delete(String id){
			eavAttrOptionDao.deleteOptionbyAttrId(id);
			this.destroy(id);
	}
	
	/**
	 * 根据entityId删除对应的所有属性值
	 * @param entityId
	 * @return
	 */
	public void deleteAttrValueByEntityId(String entityId) {
		if(StringUtils.isEmpty(entityId)) return;
		List<EavValueOptionsPo> eavValueOptionsPos = eavValueOptionsRepository.findAllByEntityId(entityId);
		for(EavValueOptionsPo eavValueOptionsPo:eavValueOptionsPos){
			eavValueOptionsDao.delete(eavValueOptionsPo.getId());
		}
		List<EavValueVarcharPo> eavValueVarcharPos = eavValueVarcharRepository.findAllByEntityId(entityId);
		for(EavValueVarcharPo eavValueVarcharPo:eavValueVarcharPos){
			eavValueVarcharDao.delete(eavValueVarcharPo.getId());
		}
		List<EavValueIntPo> eavValueIntPos = eavValueIntRepository.findAllByEntityId(entityId);
		for(EavValueIntPo eavValueIntPo:eavValueIntPos){
			eavValueIntDao.delete(eavValueIntPo.getId());
		}
		List<EavValueDecimalPo> eavValueDecimalPos = eavValueDecimalRepository.findAllByEntityId(entityId);
		for(EavValueDecimalPo eavValueDecimalPo:eavValueDecimalPos ){
			eavValueDecimalDao.delete(eavValueDecimalPo.getId());
		}
		List<EavValueDatetimePo> eavValueDatetimePos = eavValueDatetimeRepository.findAllByEntityId(entityId);
		for(EavValueDatetimePo eavValueDatetimePo:eavValueDatetimePos) {
			eavValueDatetimeDao.delete(eavValueDatetimePo.getId());	
		}
	}
	
	
	/**
	 * 根据属性集setKey和实体id，保存对应的属性值
	 * @param datas
	 * @param entityId
	 * @param setKey
	 * @return
	 */
	@SKGCacheEvict(db=RedisConstants.EAV,type="all")
	 public void saveAttrValue(Map<String,Object> datas,String entityId,String setKey) throws ParseException{
		 if(datas!=null&&datas.size()!=0&&!StringUtils.isEmpty(setKey)){
			 Map<String, Object> attrValueMap = 	getAttrDatas(datas);
			 EavSetPo	eavSetPo = eavSetRepository.findBySetKey(setKey);
			if(eavSetPo!=null){
				for(Iterator<String> it = attrValueMap.keySet().iterator();it.hasNext();){
					String attrName = it.next();
					Object attrValue = attrValueMap.get(attrName);
					if(attrValue==null||StringUtils.isEmpty(attrValue.toString())) continue;
					saveAttrValue(entityId,eavSetPo.getId(),eavSetPo.getKey(),attrName,attrValue);
				}		
			}	
		 }
	}
	/**
	 * 对于直连属性，保存对应的属性值
	 * @param datas
	 * @param entityId
	 * @return
	 */
	@SKGCacheEvict(db=RedisConstants.EAV,type="all")
	 public void saveAttrValue(Map<String,Object> datas,String entityId) throws ParseException{
		 if(datas!=null&& datas.size()!=0&&entityId!=null){
			 Map<String, Object> attrValueMap = 	getAttrDatas(datas);
				Map<String,Object> params=new HashMap<String,Object>();
				params.put("entityId",entityId);
				for(Iterator<String> it = attrValueMap.keySet().iterator();it.hasNext();){
					String attrName = it.next();
					Object attrValue = attrValueMap.get(attrName);
					if(attrName==null||StringUtils.isEmpty(attrName.toString())) continue;
					saveAttrValue(entityId,null,null,attrName,attrValue);
				}
			}
	}
	/**
	 * 保存属性值
	 * @param entityId
	 * @param setId
	 * @param setKey
	 * @param attrId
	 * @param attrValue
	 * @return
	 */
	@SKGCacheEvict(db=RedisConstants.EAV,type="all")
	 public void saveAttrValue(String entityId,String setId,String setKey,String attrId,Object attrValue) throws ParseException{
		 EavAttributePo eavAttributePo = eavAttributeQueryDao.get(attrId);
		if(eavAttributePo!=null){
				if(eavAttributePo.getDataType().equals("varchar")){
					EavValueVarcharPo oldPo = eavValueVarcharRepository.findByProdAttr(entityId,eavAttributePo.getId());
					if(oldPo!=null) eavValueVarcharDao.delete(oldPo.getId());
					EavValueVarcharPo eavValueVarcharPo = new  EavValueVarcharPo();
					eavValueVarcharPo.setAttrId(eavAttributePo.getId());
					eavValueVarcharPo.setAttrKey(eavAttributePo.getKey());
					eavValueVarcharPo.setRelType(eavAttributePo.getRelType());
					eavValueVarcharPo.setSetKey(setKey);
					eavValueVarcharPo.setSetId(setId);
					eavValueVarcharPo.setEntityId(entityId);
					eavValueVarcharPo.setValue((String)attrValue);
					EavValueVarchar eavValueVarchar = eavValueVarcharRepository.newInstance(eavValueVarcharPo);
					eavValueVarchar.save();
				}
				else if(eavAttributePo.getDataType().equals("int")){
					EavValueIntPo oldPo = eavValueIntRepository.findByProdAttr(entityId,eavAttributePo.getId());
					if(oldPo!=null) eavValueIntDao.delete(oldPo.getId());
					EavValueIntPo eavValueIntPo = new  EavValueIntPo();
					eavValueIntPo.setAttrId(eavAttributePo.getId());
					eavValueIntPo.setAttrKey(eavAttributePo.getKey());
					eavValueIntPo.setRelType(eavAttributePo.getRelType());
					eavValueIntPo.setSetKey(setKey);
					eavValueIntPo.setSetId(setId);
					eavValueIntPo.setEntityId(entityId);
					eavValueIntPo.setValue(Long.valueOf(String.valueOf(attrValue)).longValue());
					EavValueInt eavValueInt = eavValueIntRepository.newInstance(eavValueIntPo);
					eavValueInt.save();
				}
				else if(eavAttributePo.getDataType().equals("datetime")){
					EavValueDatetimePo oldPo = eavValueDatetimeRepository.findByProdAttr(entityId,eavAttributePo.getId());
					if(oldPo!=null) eavValueDatetimeDao.delete(oldPo.getId());
					EavValueDatetimePo eavValueDatetimePo = new EavValueDatetimePo();
					eavValueDatetimePo.setAttrId(eavAttributePo.getId());
					eavValueDatetimePo.setAttrKey(eavAttributePo.getKey());
					eavValueDatetimePo.setRelType(eavAttributePo.getRelType());
					eavValueDatetimePo.setSetKey(setKey);
					eavValueDatetimePo.setSetId(setId);
					eavValueDatetimePo.setEntityId(entityId);
					 SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					eavValueDatetimePo.setValue(datetimeFormat.parse((String)attrValue));
					EavValueDatetime eavValueDatetime = eavValueDatetimeRepository.newInstance(eavValueDatetimePo);
					eavValueDatetime.save();
				}
				else if(eavAttributePo.getDataType().equals("decimal")){
					EavValueDecimalPo oldPo = eavValueDecimalRepository.findByProdAttr(entityId,eavAttributePo.getId());
					if(oldPo!=null) eavValueDecimalDao.delete(oldPo.getId());
					EavValueDecimalPo eavValueDecimalPo = new EavValueDecimalPo();
					eavValueDecimalPo.setAttrId(eavAttributePo.getId());
					eavValueDecimalPo.setAttrKey(eavAttributePo.getKey());
					eavValueDecimalPo.setRelType(eavAttributePo.getRelType());
					eavValueDecimalPo.setSetKey(setKey);
					eavValueDecimalPo.setSetId(setId);
					eavValueDecimalPo.setEntityId(entityId);
					eavValueDecimalPo.setValue(Double.parseDouble(attrValue.toString()));
					EavValueDecimal eavValueDecimal = eavValueDecimalRepository.newInstance(eavValueDecimalPo);
					eavValueDecimal.save();
				}else if(eavAttributePo.getDataType().equals("options")){
					String attrValues = "";
					String optionIds = "";
					String optionLabels = "";
					if(eavAttributePo.getOpSelType().equals("checkbox")){
						String[] tmp ={};
						if(attrValue.getClass().equals(String.class)){
							tmp =new String[1];
							tmp[0] =attrValue.toString();
						}else{
							 tmp =(String[])attrValue;
						}
						for(int i=0;i<tmp.length;i++)
						{
							EavAttrOptionPo eavAttrOptionPo = eavAttrOptionQueryDao.get(tmp[i]);
							if(i!=0) {
								attrValues+=",";
								optionIds +=",";
								optionLabels +=",";
							}
							attrValues += tmp[i];
							optionIds += eavAttrOptionPo.getId();
							optionLabels += eavAttrOptionPo.getLabel();
						}
					}
					else {
						attrValues=(String)attrValue;
						EavAttrOptionPo eavAttrOptionPo = eavAttrOptionQueryDao.get(attrValues);
						optionIds = eavAttrOptionPo.getId();
						optionLabels = eavAttrOptionPo.getLabel();
					}
					EavValueOptionsPo oldPo = eavValueOptionsRepository.findByProdAttr(entityId,eavAttributePo.getId());
					if(oldPo!=null) eavValueOptionsDao.delete(oldPo.getId());
					EavValueOptionsPo eavValueOptionsPo = new EavValueOptionsPo();
					eavValueOptionsPo.setAttrId(eavAttributePo.getId());
					eavValueOptionsPo.setAttrKey(eavAttributePo.getKey());
					eavValueOptionsPo.setRelType(eavAttributePo.getRelType());
					eavValueOptionsPo.setSetKey(setKey);
					eavValueOptionsPo.setSetId(setId);
					eavValueOptionsPo.setEntityId(entityId);
					eavValueOptionsPo.setOptionValues(attrValues);
					eavValueOptionsPo.setOptionIds(optionIds);
					eavValueOptionsPo.setOptionLabels(optionLabels);
					EavValueOptions eavValueOptions = eavValueOptionsRepository.newInstance(eavValueOptionsPo);
					eavValueOptions.save();
				}
			}
	 }
	/**
	 * 获取页面传过来的属性ID以及属性值
	 * @param entityId
	 * @param setId
	 * @param setKey
	 * @param attrId
	 * @param attrValue
	 * @return
	 */
	private Map<String, Object> getAttrDatas(Map<String, Object> datas){
		Map<String, Object> paramValueMap = new HashMap<String, Object>();
		 for(Iterator<String> it = datas.keySet().iterator();it.hasNext();){
				String paramNamePost = it.next();
				if(paramNamePost.startsWith("attr_")){
					Object value = datas.get(paramNamePost);
					paramValueMap.put(paramNamePost.substring(5), value);
				}
			}
		 return paramValueMap;
	}
	/**
	 * 保存属性选项
	 * @param attrId
	 * @param eavAttrOptionPos
	 * @return
	 */
	private void saveEavAttrOptions(String attrId, List<EavAttrOptionPo> eavAttrOptionPos){
		List<EavAttrOptionPo> eavAttrOptionPos2 = eavAttrOptionQueryDao.findByAttrId(attrId);
		for(EavAttrOptionPo eao: eavAttrOptionPos){
			eao.setAttrId(attrId);
			if(StringUtils.isEmpty(eao.getId())){
				EavAttrOption eavAttrOption = eavAttrOptionRepository.newInstance(eao);
				eavAttrOption.save();
				}
			else{
				EavAttrOption eavAttrOption = eavAttrOptionRepository.load(eao.getId());
				eavAttrOption.getData().setLabel(eao.getLabel());
				eavAttrOption.getData().setValue(eao.getValue());
				eavAttrOption.getData().setSort(eao.getSort());
				eavAttrOption.save();
			}
			}
		for(EavAttrOptionPo eaoDB:eavAttrOptionPos2){
			Boolean newFlag=false;
			for(EavAttrOptionPo po:eavAttrOptionPos){
				if(eaoDB.getId().equals(po.getId())){
					newFlag = true;
					break;
				}
			}
			if(!newFlag){
				eavAttrOptionDao.delete(eaoDB.getId());
			}
		}
	}
}
